#include "stdafx.h"
#include "Application.h"

#include "Log.h"
#include "FileLogListener.h"
#include "Timer.h"
#include "Engine.h"

namespace Cvekas {

Application::Application(HINSTANCE instance, const std::string &name, const std::string& log_filename)
	:
instance(instance),
name(name)
{
	Log::init();
	Log::addListener(FileLogListenerPtr(new FileLogListener(log_filename)));

	video_device = VideoDevicePtr(new VideoDevice());
	Engine::video_device = video_device;

	settings = SettingsPtr(new Settings());
	Engine::settings = settings;
}

Application::~Application()
{
	Engine::gui.reset();
	Engine::sound_manager.reset();
	Engine::input.reset();
	Engine::video_device.reset();
	Engine::settings.reset();

	gui.reset();
	input.reset();

	effect_manager.reset();
	gpu_buffer_manager.reset();
	texture_manager.reset();

	main_renderer.reset();
	video_device.reset();

	window.reset();

	sound_manager.reset();

	settings.reset();

	Log::release();
}

void Application::run()
{
	initVideoDevice();

	if(!bool(window))
	{
		LOG("Window not properly initialized!. Quitting.");
		return;
	}

	if(!bool(video_device))
		throw EXCEPTION("VideoDevice not properly initialized!");

	main_renderer = video_device->createRenderer();

	texture_manager = video_device->getTextureManager();
	gpu_buffer_manager = video_device->getGpuBufferManager();
	effect_manager = video_device->getEffectManager();

	sound_manager = SoundManagerPtr(new SoundManager(window->getHandle()));
	Engine::sound_manager = sound_manager;

	input = InputPtr(new Input(window->getHandle()));
	Engine::input = input;

	Timer::reset();

	init();

	while(window->update())
	{
		Timer::update();
		sound_manager->update();

		if(!video_device->ensureDevice())
		{
			Sleep(50);
			continue;
		}

		if(!update())
			break;

		if(!render())
			break;
	}

	close();
}

void Application::setGUI(GUIPtr gui)
{
	this->gui = gui;
	Engine::gui = gui;
}

} // namespace
